﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Office.Interop.Excel;

namespace DataScripter.Excel
{
	class ExcelApp : IDisposable, IExcel
	{
		public ExcelApp()
		{
			Application = GetActiveExcelApplication() ?? new Application();
			//Application.RegisterXLL("Analys32.xll");
			Application.Visible = true;
		}

		public static string SafeExcelSheetName(string name)
		{
			return name.Replace('/', ' ')
				.Replace('\\', ' ')
				.Replace('*', ' ')
				.Replace('?', ' ')
				.Replace('[', ' ')
				.Replace(']', ' ');
		}

		private static Application GetActiveExcelApplication()
		{
			Process[] excelProcesses = Process.GetProcessesByName("EXCEL");
			if (excelProcesses.Length == 0)
			{
				/*Process excelProcess =*/ Process.Start("Excel.exe");
				Thread.Sleep(1000);
			}
			try
			{
				return (Application)Marshal.GetActiveObject("Excel.Application");
			}
			catch //(Exception e)
			{
				return null;
			}
		}

		public object GetRange(string rangeIdentifier)
		{
			return (IRange) Application.get_Range(rangeIdentifier, Missing.Value);
		}

		public void AddWorkbook()
		{
			Workbook = Application.Workbooks.Add(Missing.Value);
			Workbook.Activate();
			Workbook.PrecisionAsDisplayed = true;

			Sheets worksheets = Workbook.Worksheets;
			for (int i = worksheets.Count; i > 1; i--)
			{
				Worksheet o = (Worksheet)worksheets[i];
				o.Delete();
			}
			Sheet = (Worksheet)Workbook.Worksheets[1];
			Sheet.Activate();
		}

	    private _Workbook Workbook { get; set; }
		public _Worksheet Sheet { get; private set; }
		public Application Application { get; private set; }

		#region Implementation of IDisposable

		public void Dispose()
		{
			Application.Quit();
		}

		#endregion

		public ICell GetFirstCell()
		{
			return new Cell(this, "A1");
		}

		public void AutoFitColumn(string columnRange)
		{
			Range range = (Range) Sheet.Columns[columnRange, Missing.Value];
			range.EntireColumn.AutoFit();
		}

		public void HideColumn(string columnRange)
		{
			Range range = (Range)Sheet.Columns[columnRange, Missing.Value];
			range.EntireColumn.Hidden = true;
		}

		public void ShowOutlineRowLevels(int levels)
		{
			Sheet.Outline.ShowLevels(1, Missing.Value);
		}

		public void GroupRows(int fromRow, int toRow)
		{
			Range rows = (Range) Sheet.Rows[string.Format("{0}:{1}", fromRow, toRow), Missing.Value];
			rows.Group(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
		}
	}
}
